package com.winner.data.controller;

import java.util.Optional;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.winner.data.exception.R;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;

/**
 * 文件上传下载
 *
 * @author wangxinle5
 * @since 2023-01-03
 */
@Slf4j
@RestController
@RequestMapping("/minio")
public class MinioController extends BaseController {

    @Resource
    private MinioClient minioClient;

    @Value("${minio.url}")
    private String url;

    /**
     * 上传文件到minio(指定bucketName和目录层级名为dirName下的文件内容是file)
     *
     * @param file file
     * @param bucketName bucketName
     * @param dirName 模拟文件夹 cc/dd/ 必须以/结尾,或者传空串
     * @return 结果
     */
    @PostMapping(value = "/upload")
    public R upload(@RequestPart("file") MultipartFile file, String bucketName, String dirName) {
        String originalFilename = file.getOriginalFilename();
        // 拿到扩展名,即.pdf
        String extension = originalFilename.substring(originalFilename.lastIndexOf(StrUtil.DOT) + 1);
        // MinIO 不支持传统文件夹，但通过对象键中的路径结构（例如 myminio/1.pdf）来模拟文件夹。
        String objectName = Optional.ofNullable(dirName).orElse(StrUtil.EMPTY) + IdUtil.getSnowflakeNextIdStr()
            + StrUtil.DOT + extension.toLowerCase();
        try {
            // 设置 Content-Type 为 application/pdf, 在存储时被正确标记其类型，这有助于后续处理
            minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
                .stream(file.getInputStream(), file.getSize(), -1).contentType("application/" + extension).build());
        } catch (Exception e) {
            throw new RuntimeException("上传失败");
        }
        // 直接构建永久 URL（仅适用于公开可读对象）,这个url在查询文件时候需要返回
        String finalUrl = url + StrUtil.SLASH + bucketName + StrUtil.SLASH + objectName;
        log.info("永久URL is {}", finalUrl);
        return R.success(finalUrl);
    }

}
